package com.gitee.wsl.time.chinese.util

import kotlin.math.abs

/**
 * 佛历因果犯忌
 *
 * @author 6tail
 */
class FotoFestival(
    /**
     * 是日何日，如：雷斋日
     */
    val name: String,
    /**
     * 犯之因果，如：犯者夺纪
     */
    val result: String = "",
    /**
     * 是否每月同
     */
    val isEveryMonth: Boolean = false,
    /**
     * 备注，如：宜先一日即戒
     */
    val remark: String = "",
) {

    override fun toString(): String {
        return name!!
    }

    fun toFullString(): String {
        val s = StringBuilder()
        s.append(name)
        if (null != result && result.length > 0) {
            s.append(" ")
            s.append(result)
        }
        if (null != remark && remark.length > 0) {
            s.append(" ")
            s.append(remark)
        }
        return s.toString()
    }
}


/**
 * 佛历工具
 *
 * @author 6tail
 */
object FotoUtil {
    /**
     * 观音斋日期
     */
    val DAY_ZHAI_GUAN_YIN: Array<String> = arrayOf<String>(
        "1-8",
        "2-7",
        "2-9",
        "2-19",
        "3-3",
        "3-6",
        "3-13",
        "4-22",
        "5-3",
        "5-17",
        "6-16",
        "6-18",
        "6-19",
        "6-23",
        "7-13",
        "8-16",
        "9-19",
        "9-23",
        "10-2",
        "11-19",
        "11-24",
        "12-25"
    )

    private const val DJ = "犯者夺纪"
    private const val JS = "犯者减寿"
    private const val SS = "犯者损寿"
    private const val XL = "犯者削禄夺纪"
    private const val JW = "犯者三年内夫妇俱亡"

    private val Y: FotoFestival = FotoFestival("杨公忌")
    private val T: FotoFestival = FotoFestival("四天王巡行", "", true)
    private val D: FotoFestival = FotoFestival("斗降", DJ, true)
    private val S: FotoFestival = FotoFestival("月朔", DJ, true)
    private val W: FotoFestival = FotoFestival("月望", DJ, true)
    private val H: FotoFestival = FotoFestival("月晦", JS, true)
    private val L: FotoFestival = FotoFestival("雷斋日", JS, true)
    private val J: FotoFestival = FotoFestival("九毒日", "犯者夭亡，奇祸不测")
    private val R: FotoFestival = FotoFestival("人神在阴", "犯者得病", true, "宜先一日即戒")
    private val M: FotoFestival = FotoFestival("司命奏事", JS, true, "如月小，即戒廿九")
    private val HH: FotoFestival = FotoFestival("月晦", JS, true, "如月小，即戒廿九")

    /**
     * 因果犯忌
     */
    val FESTIVAL: Map<String, List<FotoFestival>> = mutableMapOf<String, List<FotoFestival>>().apply{
            put("1-1", listOf(FotoFestival("天腊，玉帝校世人神气禄命", XL), S))
            put("1-3", listOf(FotoFestival("万神都会", DJ), D))
            put("1-5", listOf(FotoFestival("五虚忌")))
            put("1-6", listOf(FotoFestival("六耗忌"), L))
            put("1-7", listOf(FotoFestival("上会日", SS)))
            put("1-8", listOf(FotoFestival("五殿阎罗天子诞", DJ), T))
            put("1-9", listOf(FotoFestival("玉皇上帝诞", DJ)))
            put("1-13", listOf(Y))
            put("1-14", listOf(FotoFestival("三元降", JS), T))
            put("1-15", listOf(FotoFestival("三元降", JS), FotoFestival("上元神会", DJ), W, T))
            put("1-16", listOf(FotoFestival("三元降", JS)))
            put("1-19", listOf(FotoFestival("长春真人诞")))
            put("1-23", listOf(FotoFestival("三尸神奏事"), T))
            put("1-25", listOf(H, FotoFestival("天地仓开日", "犯者损寿，子带疾")))
            put("1-27", listOf(D))
            put("1-28", listOf(R))
            put("1-29", listOf(T))
            put("1-30", listOf(HH, M, T))
            put("2-1", listOf(FotoFestival("一殿秦广王诞", DJ), S))
            put("2-2", listOf(FotoFestival("万神都会", DJ), FotoFestival("福德土地正神诞", "犯者得祸")))
            put("2-3", listOf(FotoFestival("文昌帝君诞", XL), D))
            put("2-6", listOf(FotoFestival("东华帝君诞"), L))
            put(
                "2-8",
                listOf(
                    FotoFestival("释迦牟尼佛出家", DJ),
                    FotoFestival("三殿宋帝王诞", DJ),
                    FotoFestival("张大帝诞", DJ),
                    T
                )
            )
            put("2-11", listOf(Y))
            put("2-14", listOf(T))
            put(
                "2-15",
                listOf(
                    FotoFestival("释迦牟尼佛涅槃", XL),
                    FotoFestival("太上老君诞", XL),
                    FotoFestival("月望", XL, true),
                    T
                )
            )
            put("2-17", listOf(FotoFestival("东方杜将军诞")))
            put("2-18", listOf(FotoFestival("四殿五官王诞", XL), FotoFestival("至圣先师孔子讳辰", XL)))
            put("2-19", listOf(FotoFestival("观音大士诞", DJ)))
            put("2-21", listOf(FotoFestival("普贤菩萨诞")))
            put("2-23", listOf(T))
            put("2-25", listOf(H))
            put("2-27", listOf(D))
            put("2-28", listOf(R))
            put("2-29", listOf(T))
            put("2-30", listOf(HH, M, T))
            put("3-1", listOf(FotoFestival("二殿楚江王诞", DJ), S))
            put("3-3", listOf(FotoFestival("玄天上帝诞", DJ), D))
            put("3-6", listOf(L))
            put("3-8", listOf(FotoFestival("六殿卞城王诞", DJ), T))
            put("3-9", listOf(FotoFestival("牛鬼神出", "犯者产恶胎"), Y))
            put("3-12", listOf(FotoFestival("中央五道诞")))
            put("3-14", listOf(T))
            put("3-15", listOf(FotoFestival("昊天上帝诞", DJ), FotoFestival("玄坛诞", DJ), W, T))
            put("3-16", listOf(FotoFestival("准提菩萨诞", DJ)))
            put("3-19", listOf(FotoFestival("中岳大帝诞"), FotoFestival("后土娘娘诞"), FotoFestival("三茅降")))
            put("3-20", listOf(FotoFestival("天地仓开日", SS), FotoFestival("子孙娘娘诞")))
            put("3-23", listOf(T))
            put("3-25", listOf(H))
            put("3-27", listOf(FotoFestival("七殿泰山王诞"), D))
            put("3-28", listOf(R, FotoFestival("苍颉至圣先师诞", XL), FotoFestival("东岳大帝诞")))
            put("3-29", listOf(T))
            put("3-30", listOf(HH, M, T))
            put("4-1", listOf(FotoFestival("八殿都市王诞", DJ), S))
            put("4-3", listOf(D))
            put("4-4", listOf(FotoFestival("万神善会", "犯者失瘼夭胎"), FotoFestival("文殊菩萨诞")))
            put("4-6", listOf(L))
            put("4-7", listOf(FotoFestival("南斗、北斗、西斗同降", JS), Y))
            put(
                "4-8",
                listOf(
                    FotoFestival("释迦牟尼佛诞", DJ),
                    FotoFestival("万神善会", "犯者失瘼夭胎"),
                    FotoFestival("善恶童子降", "犯者血死"),
                    FotoFestival("九殿平等王诞"),
                    T
                )
            )
            put("4-14", listOf(FotoFestival("纯阳祖师诞", JS), T))
            put("4-15", listOf(W, FotoFestival("钟离祖师诞"), T))
            put("4-16", listOf(FotoFestival("天地仓开日", SS)))
            put("4-17", listOf(FotoFestival("十殿转轮王诞", DJ)))
            put("4-18", listOf(FotoFestival("天地仓开日", SS), FotoFestival("紫徽大帝诞", SS)))
            put("4-20", listOf(FotoFestival("眼光圣母诞")))
            put("4-23", listOf(T))
            put("4-25", listOf(H))
            put("4-27", listOf(D))
            put("4-28", listOf(R))
            put("4-29", listOf(T))
            put("4-30", listOf(HH, M, T))
            put("5-1", listOf(FotoFestival("南极长生大帝诞", DJ), S))
            put("5-3", listOf(D))
            put("5-5", listOf(FotoFestival("地腊", XL), FotoFestival("五帝校定生人官爵", XL), J, Y))
            put("5-6", listOf(J, L))
            put("5-7", listOf(J))
            put("5-8", listOf(FotoFestival("南方五道诞"), T))
            put("5-11", listOf(FotoFestival("天地仓开日", SS), FotoFestival("天下都城隍诞")))
            put("5-12", listOf(FotoFestival("炳灵公诞")))
            put("5-13", listOf(FotoFestival("关圣降", XL)))
            put("5-14", listOf(FotoFestival("夜子时为天地交泰", JW), T))
            put("5-15", listOf(W, J, T))
            put("5-16", listOf(FotoFestival("九毒日", JW), FotoFestival("天地元气造化万物之辰", JW)))
            put("5-17", listOf(J))
            put("5-18", listOf(FotoFestival("张天师诞")))
            put("5-22", listOf(FotoFestival("孝娥神诞", DJ)))
            put("5-23", listOf(T))
            put("5-25", listOf(J, H))
            put("5-26", listOf(J))
            put("5-27", listOf(J, D))
            put("5-28", listOf(R))
            put("5-29", listOf(T))
            put("5-30", listOf(HH, M, T))
            put("6-1", listOf(S))
            put("6-3", listOf(FotoFestival("韦驮菩萨圣诞"), D, Y))
            put("6-5", listOf(FotoFestival("南赡部洲转大轮", SS)))
            put("6-6", listOf(FotoFestival("天地仓开日", SS), L))
            put("6-8", listOf(T))
            put("6-10", listOf(FotoFestival("金粟如来诞")))
            put("6-14", listOf(T))
            put("6-15", listOf(W, T))
            put("6-19", listOf(FotoFestival("观世音菩萨成道", DJ)))
            put("6-23", listOf(FotoFestival("南方火神诞", "犯者遭回禄"), T))
            put("6-24", listOf(FotoFestival("雷祖诞", XL), FotoFestival("关帝诞", XL)))
            put("6-25", listOf(H))
            put("6-27", listOf(D))
            put("6-28", listOf(R))
            put("6-29", listOf(T))
            put("6-30", listOf(HH, M, T))
            put("7-1", listOf(S, Y))
            put("7-3", listOf(D))
            put("7-5", listOf(FotoFestival("中会日", SS, false, "一作初七")))
            put("7-6", listOf(L))
            put(
                "7-7",
                listOf(FotoFestival("道德腊", XL), FotoFestival("五帝校生人善恶", XL), FotoFestival("魁星诞", XL))
            )
            put("7-8", listOf(T))
            put("7-10", listOf(FotoFestival("阴毒日", "", false, "大忌")))
            put("7-12", listOf(FotoFestival("长真谭真人诞")))
            put("7-13", listOf(FotoFestival("大势至菩萨诞", JS)))
            put("7-14", listOf(FotoFestival("三元降", JS), T))
            put("7-15", listOf(W, FotoFestival("三元降", DJ), FotoFestival("地官校籍", DJ), T))
            put("7-16", listOf(FotoFestival("三元降", JS)))
            put("7-18", listOf(FotoFestival("西王母诞", DJ)))
            put("7-19", listOf(FotoFestival("太岁诞", DJ)))
            put("7-22", listOf(FotoFestival("增福财神诞", XL)))
            put("7-23", listOf(T))
            put("7-25", listOf(H))
            put("7-27", listOf(D))
            put("7-28", listOf(R))
            put("7-29", listOf(Y, T))
            put("7-30", listOf(FotoFestival("地藏菩萨诞", DJ), HH, M, T))
            put("8-1", listOf(S, FotoFestival("许真君诞")))
            put("8-3", listOf(D, FotoFestival("北斗诞", XL), FotoFestival("司命灶君诞", "犯者遭回禄")))
            put("8-5", listOf(FotoFestival("雷声大帝诞", DJ)))
            put("8-6", listOf(L))
            put("8-8", listOf(T))
            put("8-10", listOf(FotoFestival("北斗大帝诞")))
            put("8-12", listOf(FotoFestival("西方五道诞")))
            put("8-14", listOf(T))
            put("8-15", listOf(W, FotoFestival("太明朝元", "犯者暴亡", false, "宜焚香守夜"), T))
            put("8-16", listOf(FotoFestival("天曹掠刷真君降", "犯者贫夭")))
            put("8-18", listOf(FotoFestival("天人兴福之辰", "", false, "宜斋戒，存想吉事")))
            put("8-23", listOf(FotoFestival("汉恒候张显王诞"), T))
            put("8-24", listOf(FotoFestival("灶君夫人诞")))
            put("8-25", listOf(H))
            put("8-27", listOf(D, FotoFestival("至圣先师孔子诞", XL), Y))
            put("8-28", listOf(R, FotoFestival("四天会事")))
            put("8-29", listOf(T))
            put("8-30", listOf(FotoFestival("诸神考校", "犯者夺算"), HH, M, T))
            put("9-1", listOf(S, FotoFestival("南斗诞", XL), FotoFestival("北斗九星降世", DJ, false, "此九日俱宜斋戒")))
            put("9-3", listOf(D, FotoFestival("五瘟神诞")))
            put("9-6", listOf(L))
            put("9-8", listOf(T))
            put("9-9", listOf(FotoFestival("斗母诞", XL), FotoFestival("酆都大帝诞"), FotoFestival("玄天上帝飞升")))
            put("9-10", listOf(FotoFestival("斗母降", DJ)))
            put("9-11", listOf(FotoFestival("宜戒")))
            put("9-13", listOf(FotoFestival("孟婆尊神诞")))
            put("9-14", listOf(T))
            put("9-15", listOf(W, T))
            put("9-17", listOf(FotoFestival("金龙四大王诞", "犯者遭水厄")))
            put("9-19", listOf(FotoFestival("日宫月宫会合", JS), FotoFestival("观世音菩萨诞", JS)))
            put("9-23", listOf(T))
            put("9-25", listOf(H, Y))
            put("9-27", listOf(D))
            put("9-28", listOf(R))
            put("9-29", listOf(T))
            put("9-30", listOf(FotoFestival("药师琉璃光佛诞", "犯者危疾"), HH, M, T))
            put("10-1", listOf(S, FotoFestival("民岁腊", DJ), FotoFestival("四天王降", "犯者一年内死")))
            put("10-3", listOf(D, FotoFestival("三茅诞")))
            put("10-5", listOf(FotoFestival("下会日", JS), FotoFestival("达摩祖师诞", JS)))
            put("10-6", listOf(L, FotoFestival("天曹考察", DJ)))
            put("10-8", listOf(FotoFestival("佛涅槃日", "", false, "大忌色欲"), T))
            put("10-10", listOf(FotoFestival("四天王降", "犯者一年内死")))
            put("10-11", listOf(FotoFestival("宜戒")))
            put("10-14", listOf(FotoFestival("三元降", JS), T))
            put("10-15", listOf(W, FotoFestival("三元降", DJ), FotoFestival("下元水府校籍", DJ), T))
            put("10-16", listOf(FotoFestival("三元降", JS), T))
            put("10-23", listOf(Y, T))
            put("10-25", listOf(H))
            put("10-27", listOf(D, FotoFestival("北极紫徽大帝降")))
            put("10-28", listOf(R))
            put("10-29", listOf(T))
            put("10-30", listOf(HH, M, T))
            put("11-1", listOf(S))
            put("11-3", listOf(D))
            put("11-4", listOf(FotoFestival("至圣先师孔子诞", XL)))
            put("11-6", listOf(FotoFestival("西岳大帝诞")))
            put("11-8", listOf(T))
            put("11-11", listOf(FotoFestival("天地仓开日", DJ), FotoFestival("太乙救苦天尊诞", DJ)))
            put("11-14", listOf(T))
            put(
                "11-15",
                listOf(
                    FotoFestival("月望", "上半夜犯男死 下半夜犯女死"),
                    FotoFestival("四天王巡行", "上半夜犯男死 下半夜犯女死")
                )
            )
            put("11-17", listOf(FotoFestival("阿弥陀佛诞")))
            put("11-19", listOf(FotoFestival("太阳日宫诞", "犯者得奇祸")))
            put("11-21", listOf(Y))
            put("11-23", listOf(FotoFestival("张仙诞", "犯者绝嗣"), T))
            put("11-25", listOf(FotoFestival("掠刷大夫降", "犯者遭大凶"), H))
            put("11-26", listOf(FotoFestival("北方五道诞")))
            put("11-27", listOf(D))
            put("11-28", listOf(R))
            put("11-29", listOf(T))
            put("11-30", listOf(HH, M, T))
            put("12-1", listOf(S))
            put("12-3", listOf(D))
            put("12-6", listOf(FotoFestival("天地仓开日", JS), L))
            put("12-7", listOf(FotoFestival("掠刷大夫降", "犯者得恶疾")))
            put(
                "12-8",
                listOf(
                    FotoFestival("王侯腊", DJ),
                    FotoFestival("释迦如来成佛之辰"),
                    T,
                    FotoFestival("初旬内戊日，亦名王侯腊", DJ)
                )
            )
            put("12-12", listOf(FotoFestival("太素三元君朝真")))
            put("12-14", listOf(T))
            put("12-15", listOf(W, T))
            put("12-16", listOf(FotoFestival("南岳大帝诞")))
            put("12-19", listOf(Y))
            put("12-20", listOf(FotoFestival("天地交道", "犯者促寿")))
            put("12-21", listOf(FotoFestival("天猷上帝诞")))
            put("12-23", listOf(FotoFestival("五岳诞降"), T))
            put("12-24", listOf(FotoFestival("司今朝天奏人善恶", "犯者得大祸")))
            put("12-25", listOf(FotoFestival("三清玉帝同降，考察善恶", "犯者得奇祸"), H))
            put("12-27", listOf(D))
            put("12-28", listOf(R))
            put("12-29", listOf(FotoFestival("华严菩萨诞"), T))
            put("12-30", listOf(FotoFestival("诸神下降，察访善恶", "犯者男女俱亡")))
    }

    /**
     * 纪念日
     */
    val OTHER_FESTIVAL: Map<String, List<String>> =mutableMapOf<String, List<String>>().apply{
            put("1-1", listOf("弥勒菩萨圣诞"))
            put("1-6", listOf("定光佛圣诞"))
            put("2-8", listOf("释迦牟尼佛出家"))
            put("2-15", listOf("释迦牟尼佛涅槃"))
            put("2-19", listOf("观世音菩萨圣诞"))
            put("2-21", listOf("普贤菩萨圣诞"))
            put("3-16", listOf("准提菩萨圣诞"))
            put("4-4", listOf("文殊菩萨圣诞"))
            put("4-8", listOf("释迦牟尼佛圣诞"))
            put("4-15", listOf("佛吉祥日"))
            put("4-28", listOf("药王菩萨圣诞"))
            put("5-13", listOf("伽蓝菩萨圣诞"))
            put("6-3", listOf("韦驮菩萨圣诞"))
            put("6-19", listOf("观音菩萨成道"))
            put("7-13", listOf("大势至菩萨圣诞"))
            put("7-15", listOf("佛欢喜日"))
            put("7-24", listOf("龙树菩萨圣诞"))
            put("7-30", listOf("地藏菩萨圣诞"))
            put("8-15", listOf("月光菩萨圣诞"))
            put("8-22", listOf("燃灯佛圣诞"))
            put("9-9", listOf("摩利支天菩萨圣诞"))
            put("9-19", listOf("观世音菩萨出家"))
            put("9-30", listOf("药师琉璃光佛圣诞"))
            put("10-5", listOf("达摩祖师圣诞"))
            put("10-20", listOf("文殊菩萨出家"))
            put("11-17", listOf("阿弥陀佛圣诞"))
            put("11-19", listOf("日光菩萨圣诞"))
            put("12-8", listOf("释迦牟尼佛成道"))
            put("12-23", listOf("监斋菩萨圣诞"))
            put("12-29", listOf("华严菩萨圣诞"))
    }

    /**
     * 27星宿，佛教从印度传入中国，印度把28星宿改为27星宿，把牛宿(牛金牛)纳入了女宿(女土蝠)。
     */
    val XIU_27: Array<String> = arrayOf<String>(
        "角",
        "亢",
        "氐",
        "房",
        "心",
        "尾",
        "箕",
        "斗",
        "女",
        "虚",
        "危",
        "室",
        "壁",
        "奎",
        "娄",
        "胃",
        "昴",
        "毕",
        "觜",
        "参",
        "井",
        "鬼",
        "柳",
        "星",
        "张",
        "翼",
        "轸"
    )

    /**
     * 每月初一的27星宿偏移
     */
    private val XIU_OFFSET = intArrayOf(11, 13, 15, 17, 19, 21, 24, 0, 2, 4, 7, 9)

    /**
     * 获取27星宿
     *
     * @param month 佛历月
     * @param day   佛历日
     * @return 星宿
     */
    fun getXiu(month: Int, day: Int): String {
        return XIU_27[(XIU_OFFSET[abs(month) - 1] + day - 1) % XIU_27.size]
    }
}
